﻿/*            Copyright(c) 2006-2008 Dave Sexton           *
 * http://www.codeplex.com/DocProject                      *
 * http://www.codeplex.com/DocProject/Project/License.aspx *
 ***********************************************************/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;

namespace DaveSexton.DocProject.Sandcastle
{
	internal sealed partial class MetadataGrid : UserControl
	{
		#region Public Properties
		[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public MetadataCollection Metadata
		{
			set
			{
				metadata = value;

				DataBind();
			}
		}
		#endregion

		#region Private / Protected
		private DataSet attributesDataSet;
		private MetadataCollection metadata;
		#endregion

		#region Constructors
		/// <summary>
		/// Constructs a new instance of the <see cref="MetadataGrid" /> class.
		/// </summary>
		public MetadataGrid()
		{
			InitializeComponent();

			attributesGridView.AutoGenerateColumns = false;
		}
		#endregion

		#region Methods
		private void InitializeDataGridView()
		{
			attributesGridView.DataSource = null;

			attributeColumn.Items.Clear();
			attributeColumn.Items.AddRange(new[] {
            "DocSet",
            "Product",
            "DevLang",
            "Technology",
            "TargetOS",
            "LinkGroup",
            "HelpPriority",
            "Status"});
		}
		
		public void DataBind()
		{
			InitializeDataGridView();

			if (metadata == null)
				attributesDataSet = null;
			else
			{
				attributesDataSet = Help2xProject.CreateAttributesDataSet(metadata);

				foreach (DataRow row in attributesDataSet.Tables["Attributes"].DefaultView.ToTable(true, "Name").Rows)
				{
					object name = row["Name"];

					if (!attributeColumn.Items.Contains(name))
						attributeColumn.Items.Add(name);
				}

				attributesGridView.DataSource = new BindingSource(attributesDataSet, "Attributes");
			}
		}

		private static void HandleDataGridViewError(Exception ex)
		{
			if (ex is ConstraintException)
				DocProjectEnvironment.ShowErrorDialog(ex.Message);
		}

		#region Hack
		// HACK: This event handler is a workaround for an EditOnEnter bug that prevents rows from being selected when a header is clicked.
		// This code is based on the workaround found here: https://connect.microsoft.com/VisualStudio/feedback/Workaround.aspx?FeedbackID=98504
		// The DataGridView's CellEnter and MouseClick events are used to call these methods.
		private static void SetDataGridViewEditOnEnter(DataGridView control)
		{
			control.EditMode = DataGridViewEditMode.EditOnEnter;
		}

		private static void SetDataGridViewEditOnKeystrokeOrF2(DataGridView control, int x, int y)
		{
			DataGridView.HitTestInfo hit = control.HitTest(x, y);

			if (hit.Type == DataGridViewHitTestType.RowHeader)
			{
				control.EditMode = DataGridViewEditMode.EditOnKeystrokeOrF2;
				control.EndEdit();
			}
		}
		#endregion
		#endregion

		#region Event Handlers
		/// <seealso href="http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2881077&SiteID=1">DataGridView ComboBox row as DropDown, NOT DropDownList</seealso>
		private void attributesGridView_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
		{
			if (e.ColumnIndex == attributeColumn.DisplayIndex)
			{
				string value = e.FormattedValue as string;

				if (value != null && (value = value.Trim()).Length > 0)
				{
					if (!attributeColumn.Items.Contains(value))
						attributeColumn.Items.Add(value);

					attributesGridView[e.ColumnIndex, e.RowIndex].Value = value;
				}
			}
		}

		/// <seealso href="http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2881077&SiteID=1">DataGridView ComboBox row as DropDown, NOT DropDownList</seealso>
		private void attributesGridView_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
		{
			if (attributesGridView.CurrentCellAddress.X == attributeColumn.DisplayIndex)
			{
				ComboBox combo = e.Control as ComboBox;

				if (combo != null)
					combo.DropDownStyle = ComboBoxStyle.DropDown;
			}
		}

		private void attributesGridView_Validated(object sender, EventArgs e)
		{
			if (metadata != null)
				Help2xProject.FillAttributesFromDataSet(attributesDataSet, metadata);
		}

		private void attributesGridView_DataError(object sender, DataGridViewDataErrorEventArgs e)
		{
			if (e.Exception != null && e.Context == DataGridViewDataErrorContexts.Commit)
				HandleDataGridViewError(e.Exception);
		}

		private void attributesGridView_CellEnter(object sender, DataGridViewCellEventArgs e)
		{
			SetDataGridViewEditOnEnter(attributesGridView);
		}

		private void attributesGridView_MouseClick(object sender, MouseEventArgs e)
		{
			SetDataGridViewEditOnKeystrokeOrF2(attributesGridView, e.X, e.Y);
		}
		#endregion
	}
}
